package cloud.misiro.spring.cloud.zuul;

import cloud.misiro.spring.cloud.zuul.filters.RouteLocator;
import cloud.misiro.spring.cloud.zuul.filters.SimpleRouteLocator;
import cloud.misiro.spring.cloud.zuul.filters.ZuulProperties;
import cloud.misiro.spring.cloud.zuul.filters.post.SendResponseFilter;
import cloud.misiro.spring.cloud.zuul.filters.pre.PreDecorationFilter;
import cloud.misiro.spring.cloud.zuul.filters.route.RibbonRoutingFilter;
import cloud.misiro.spring.cloud.zuul.metrics.EmptyCounterFactory;
import cloud.misiro.spring.cloud.zuul.metrics.EmptyTracerFactory;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.filters.FilterRegistry;
import com.netflix.zuul.http.ZuulServlet;
import com.netflix.zuul.monitoring.CounterFactory;
import com.netflix.zuul.monitoring.TracerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.Map;

@Configuration
@EnableConfigurationProperties({ZuulProperties.class})
public class ZuulServerAutoConfiguration {

    @Autowired
    protected ZuulProperties zuulProperties;

    @Bean
    public ServletRegistrationBean zuulServlet() {
        return new ServletRegistrationBean<>(new ZuulServlet(), zuulProperties.getServletPath());
    }

    @Bean
    public RouteLocator simpleRouteLocator() {
        return new SimpleRouteLocator(zuulProperties);
    }

    @Bean
    public ZuulFilter preDecorationFilter(RouteLocator routeLocator) {
        return new PreDecorationFilter(routeLocator);
    }

    @Bean
    public ZuulFilter ribbonRoutingFilter(LoadBalancerClient loadBalancerClient) {
        return new RibbonRoutingFilter(loadBalancerClient);
    }

    @Bean
    public ZuulFilter sendResponseFilter() {
        return new SendResponseFilter();
    }

    @Bean
    public FilterRegistry filterRegistry(Map<String, ZuulFilter> filterMap) {
        FilterRegistry filterRegistry = FilterRegistry.instance();
        filterMap.forEach(filterRegistry::put);
        return filterRegistry;
    }

    @Bean
    public CounterFactory emptyCounterFactory() {
        CounterFactory.initialize(new EmptyCounterFactory());
        return CounterFactory.instance();
    }

    @Bean
    public TracerFactory emptyTracerFactory() {
        TracerFactory.initialize(new EmptyTracerFactory());
        return TracerFactory.instance();
    }

}
